package com.spark.core;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import freemarker.template.Template;

public class CacheManager {
	
	private static CacheManager instance = new CacheManager();
	
	private ReadWriteLock lock = new ReentrantReadWriteLock();
	private HashMap<String,SparkTemplate> sparkTemplateCache = new HashMap<String,SparkTemplate>(1000);
	private HashMap<String,Template> templateCache = new HashMap<String,Template>(1000);
	private HashMap<String,String> screenHTMLCache = new HashMap<String,String>(1000);
	private HashMap<String,Map<String,String>> tagHTMLCache = new HashMap<String,Map<String,String>>(1000);
	
	private CacheManager(){}
	
	private boolean isLock = false;
	
	public static CacheManager getInstance(){
		return instance;
	}
	
	private void lock(){
		if(isLock)
		lock.readLock().lock();
	}
	
	private void unlock(){
		if(isLock)
		lock.readLock().unlock();
	}
	
	
	public Template getTemplate(SparkTemplate st, SparkContext context) throws IOException {
		lock();
		String path = st.getFilePath();
		Template t = templateCache.get(path);
		if(t == null) {
			Reader reader = new BufferedReader(new StringReader(st.getXML()));
			try {
				t = new Template(st.getName(), reader ,context.getFreemarkerConfiguration(),"UTF-8");
			}finally{
				reader.close();
			}
			setTemplate(path, t);
		}
		unlock();
		return t;
	}
	public void setTemplate(String path, Template t){
		templateCache.put(path, t);
	}
	
	
	public String getScreenHTML(String path) throws IOException {
		lock();
		String str = screenHTMLCache.get(path);
		unlock();
		return str;
	}
	public void setScreenHTML(String path, String html){
		screenHTMLCache.put(path, html);
	}
	
	
	public String getTagHTML(String path, String id){
		lock();
		Map<String,String> map = tagHTMLCache.get(path);
		if(map == null) {
			map = new HashMap<String,String>(100);
			tagHTMLCache.put(path, map);
		}
		String str = map.get(id);
		unlock();
		return str;
	}
	public void setTagHTML(String path, String id, String html){
		Map<String,String> map = tagHTMLCache.get(path);
		if(map == null) {
			map = new HashMap<String,String>(100);
			tagHTMLCache.put(path, map);
		}
		map.put(id, html);
	}
	
	
	public SparkTemplate getSparkTemplate(String path){
		lock();
		SparkTemplate st = sparkTemplateCache.get(path);
		unlock();
		return st;
	}
	public void setSparkTemplate(String path, SparkTemplate st){
		sparkTemplateCache.put(path, st);
	}
	
	
	public void clearCache(List<String> paths){
		if(paths!=null && paths.size() > 0){
			isLock = true;
			lock();
			Iterator<String> it = paths.iterator();
			while(it.hasNext()){
				String path = it.next();
				setTemplate(path,null);
				setSparkTemplate(path,null);
				screenHTMLCache.put(path, null);
				Map<String,String> map = tagHTMLCache.get(path);
				if(map != null) {
					tagHTMLCache.put(path, null);
				}
			}
			unlock();
			isLock = false;
		}
	}
	
	
}
